//******************************************************************/
//版本说明:
//V0.1		2017-03-30	11:00	yshao	复制自SL909_G01_X32
//V2.1		2019-01-31	11:00	yshao	调整init_end和comm_en,init_mode
//******************************************************************/
//******************************************************************/
//			   全局参数定义
//******************************************************************/
//仿真模式
//`define	SIMULATION	1
//`timescale	1ps/1ps

//FPGA程序模式
`define		APP_MODE	1
//`define	TEST_MODE	2
//`define	BOOT_MODE	3

//******************************************************************/
//			   FPGA顶层
//******************************************************************/
module LL901_G04(
		input	wire		sclkin,
		output	wire		key_in,
		input	wire		s_pullup,
		
		output	wire		JP202_PIN3,
		output	wire		JP202_PIN4,
		output	wire		JP202_PIN5,
		input	wire		JP202_PIN6,

		output	wire		sa_clk,
		output	wire	[2:0]	sa_cnt,
		output	wire		sa_dqm_l,
		output	wire		sa_dqm_h,
		output	wire	[10:0]	sa_addr,
		output	wire	[1:0]	sa_bank,
		inout	tri	[31:0]	sa_data,

		input	wire		mcu_dmx_tx,		//uart2_sync,
		inout	tri		mcu_dmx_rx,		//uart3_sync,

		input	wire		mcu_fpga_ctrl,		//mcu到fpga的模式控制信号

		input	wire		mcu_spi_fpga,		//spi工作在通讯模式
		input	wire		mcu_spi_clk,
		input	wire		mcu_spi_mosi,
		output	wire		mcu_spi_miso,

		output	wire		spi2_cs,
		output	wire		spi2_clk,
		output	wire		spi2_mosi,
								
		output	wire		sd_clk,
		inout	tri		sd_cmd_sdi,
		input	wire		sd_dat0_sdo,
		input	wire		sd_dat1,
		input	wire		sd_dat2,
		inout	wire		sd_dat3_cs,
		input	wire		sd_cd,
		input	wire		sd_wp,

		input	wire		gp0_rxc,
		input	wire		gp0_rxdv,
		input	wire	[3:0]	gp0_rxd,
		output	wire		gp0_txc,
		output	wire		gp0_txen,
		output	wire	[3:0]	gp0_txd,
		
		input	wire		gp1_rxc,
		input	wire		gp1_rxdv,
		input	wire	[3:0]	gp1_rxd,
		output	wire		gp1_txc,
		output	wire		gp1_txen,
		output	wire	[3:0]	gp1_txd,

		output	wire	[7:0]	port_da,
		output	wire	[7:0]	port_le,
		inout	tri	[7:0]	port_ex,
		
		input	wire	[7:0]	port_in,
		
		output	wire		led_g
		);

//****************************************************************
//		内部信号
//****************************************************************
//复位&时钟
wire		resetb, oclk, sclk, clk_25M;
wire	[20:0]	time_us, sync_us;
wire	[1:0]	pll_lock, pll_reset;

//PHY接口
wire		sub_mode;
wire	[1:0]	depth_state;
wire	[9:0]   current_depth;

wire		rec_flag_a, rec_flag, rec_error;
wire	[7:0]	rec_data;
wire	[1:0]	force_send;
wire		send_flag, pre_flag;
wire	[7:0]	send_data;
wire	[1:0]	rec_vendor;
wire		yt_vs_pre, redu_flag, blank_flag, input_L9;
wire	[7:0]	phy_state;

//PHY设置总线相关信号
wire		init_mode, set_d_ok, ext_d_ok;
wire	[31:0]	set_addr;
wire	[7:0]	set_data, rd_data;
wire	[7:0]	mcu_rd_hub;

//MCU设置总线相关信号
wire		mcu_set_d_ok, mcu_ext_d_ok;
wire	[31:0]	mcu_set_addr;
wire	[7:0]	mcu_set_data, mcu_rd_data;

//显示数据相关
wire		vs_L9, ds_L9, h_start_L9, l2048_mode;
wire		ds_a, h_start_a, vs_sd, ds_sd, h_start_sd;
wire	[7:0]	data_L9, data_a, data_sd;
wire	[10:0]	h_num_L9, h_num_a, h_num_sd;

wire	[15:0]	state;
wire	[1:0]	color_restore_type;
wire	[7:0]	testmode;
wire	[8:0]	cascade_light;

reg	[5:0]	count_34ms;
reg		vs_34ms, vs, ds, h_start;
reg	[7:0]	data;
reg	[10:0]	h_num;

//输出模块接口信号
wire		vs_out;
wire		mem_read_req, mem_read_last, mem_read_ack, mem_data_sync;
wire	[11:0]	mem_h_addr, mem_l_addr;
wire	[31:0]	mem_read_data;	

//输出控制信号
wire		out_sync;
wire 	[15:0]	out_data, out_data_n;
wire		clk_out, clk_out_n;

//DMX输出信号
wire	[1:0]	dmx_mode;
wire		dmx_send_flag, mcu_dmx_ten;
wire	[7:0]	out_data_dmx;
wire	[5:0]	device_port;

//SD播放信号
wire		sd_play_en, mcu_play_en, mcu_config_en, force_dis_en, force_send_play;

wire		sd_valid, sd_play_clk, sd_play_cmd_out, sd_play_cmd_oe;
wire	[3:0]	sd_play_data, sd_dat_mcu;
reg	[3:0]	sd_dat_dis;

wire		f_start, f_work, v_work, sd_play_flag;
wire	[40:0]	f_addr;
wire	[23:0]	f_size;
wire	[10:0]	h_size;
wire	[12:0]	l_size;

reg		local_dis_flag, mcu_play_flag;

//SDRAM控制信号
wire	[1:0]	frame_buf_sel;

//反馈网口信号
wire		send_flag_dis, pre_flag_dis;
wire	[7:0]	send_data_dis, sd_tout, hub_tout;

//**********调试用信号**********
wire	[31:0]	a1_tout, sa_tout, sd_f_tout;
wire	[15:0]	out_tout;

//******************************************************************/
//			   参数定义
//******************************************************************/
//程序版本信息
parameter	MAIN_FUNCTION	=  "L";		//ASCII "S"  
parameter	SUB_FUNCTION	=  "L";		//ASCII "L"  
parameter	MAIN_SOLUTION	=  9;		//"9"        
parameter	SUB_SOLUTION	=  1;		//"09"       
parameter	APPLICATION_TYPE=  "G";		//ASCII "G"  
parameter	MAIN_VERSION	=  8'd4;	//"03"       
parameter	SUB_VERSION	=  8'd5;	//"X01"
parameter	MINI_VERSION	=  8'd7;	//" "  

//模块参数设置
defparam	main_ctrl.phy_comm.state_ctrl.main_function	=MAIN_FUNCTION;
defparam	main_ctrl.phy_comm.state_ctrl.sub_function	=SUB_FUNCTION;
defparam	main_ctrl.phy_comm.state_ctrl.main_solution	=MAIN_SOLUTION;
defparam	main_ctrl.phy_comm.state_ctrl.sub_solution	=SUB_SOLUTION;
defparam	main_ctrl.phy_comm.state_ctrl.application_type	=APPLICATION_TYPE;
defparam	main_ctrl.phy_comm.state_ctrl.main_version	=MAIN_VERSION;
defparam	main_ctrl.phy_comm.state_ctrl.sub_version	=SUB_VERSION;
defparam	main_ctrl.phy_comm.state_ctrl.mini_version	=MINI_VERSION;

defparam        main_ctrl.mcu_comm.main_function		=	MAIN_FUNCTION;
defparam        main_ctrl.mcu_comm.sub_function		=	SUB_FUNCTION;
defparam        main_ctrl.mcu_comm.main_solution		=	MAIN_SOLUTION;
defparam        main_ctrl.mcu_comm.sub_solution		=	SUB_SOLUTION;
defparam        main_ctrl.mcu_comm.application_type	=	APPLICATION_TYPE;
defparam        main_ctrl.mcu_comm.main_version		=	MAIN_VERSION;
defparam        main_ctrl.mcu_comm.sub_version		=	SUB_VERSION;
defparam        main_ctrl.mcu_comm.mini_version		=	MINI_VERSION;

//**************************************************************
//			时钟和复位
//**************************************************************
sys_reset_clk sys_reset_clk(
		//输入时钟
		.sclkin(sclkin),
        
        	//输出复位和时钟
		.resetb(resetb),
		.sclk(sclk),
		.oclk(oclk),
		.sa_clk(sa_clk),
		.clk_25M(clk_25M),
        
        	//分频时钟
        	.time_us(time_us),
        	.sync_us(sync_us),
        	
		//按键检测
		.pll_lock(pll_lock),
		.pll_reset(pll_reset),
		
		//调试信号	
		.tout()   
		);

assign	pll_reset = 2'b00;
//**************************************************************
//			通讯模块
//**************************************************************
phy_interface phy_interface(
		.resetb(resetb),
		.sclk(sclk),
                
		.time_1ms(time_us[10]),
		.time_125ms(time_us[17]),	

		//其他外部相关信号
		.sub_mode(sub_mode),
		.cas_depth_adj(depth_state[1]),
		.local_depth(current_depth[7:0]),

		.tx_err_en(1'b0),

		//PORTA接口
		.gp0_rxc(gp0_rxc),
		.gp0_rxdv(gp0_rxdv),
		.gp0_rxd(gp0_rxd),
		.gp0_txc(gp0_txc),
		.gp0_txen(gp0_txen),
		.gp0_txd(gp0_txd),
		
		//PORTB接口
		.gp1_rxc(gp1_rxc),
		.gp1_rxdv(gp1_rxdv),
		.gp1_rxd(gp1_rxd),
		.gp1_txc(gp1_txc),
		.gp1_txen(gp1_txen),
		.gp1_txd(gp1_txd),
		
		//内部的接收接口
		.rec_flag_a(rec_flag_a),
		.rec_flag(rec_flag),
		.rec_data(rec_data),
		.rec_error(rec_error),
		.rec_error_sync(),
		
		//内部的发送接口
		.force_send(force_send),
		.send_flag(send_flag),
		.pre_flag(pre_flag),
		.send_data(send_data),

		//给内部的其他信号
		.input_port(input_port),
		.rec_vendor(rec_vendor),
		.yt_vs_pre(yt_vs_pre),
		.input_active(input_L9),
		.redu_flag(redu_flag),
		.blank_flag(blank_flag),
		.phy_state(phy_state),
		
		.tout()
		);
		
//**************************************************************
//			FPGA主控逻辑
//**************************************************************
main_ctrl main_ctrl(
		//复位时钟，按键，Led
		.resetb(resetb),
		.sclk(sclk),

		.sync_us(sync_us),
		
		//按键和指示灯
		.key_in(key_in),
		.led_g(led_g),

                //外部MCU通讯接口
		.mcu_fpga_ctrl(mcu_fpga_ctrl),
		
		.mcu_spi_fpga(mcu_spi_fpga),
		.mcu_spi_clk(mcu_spi_clk),
		.mcu_spi_mosi(mcu_spi_mosi),
		.mcu_spi_miso(mcu_spi_miso),

		.spi2_cs(spi2_cs),
		.spi2_clk(spi2_clk),
		.spi2_mosi(spi2_mosi),

		//PHY通讯接口
		.sub_mode(sub_mode),
		.depth_state(depth_state),
		.current_depth(current_depth),

		.input_L9(input_L9),
		.rec_vendor(rec_vendor),
		
		.rec_flag_a(rec_flag_a),
		.rec_flag(rec_flag),
		.rec_data(rec_data),
		.rec_error(rec_error),
		.rec_error_sync(),
		
		.force_send(force_send),
		.send_flag(send_flag),
		.pre_flag(pre_flag),
		.send_data(send_data),
		
		//PHY总线接口
		.init_mode(init_mode),
		.set_d_ok(set_d_ok),
		.ext_d_ok(ext_d_ok),
		.set_addr(set_addr),
		.set_data(set_data),
		.rd_data(rd_data),

		//MCU总线接口
		.mcu_set_d_ok(mcu_set_d_ok),
		.mcu_ext_d_ok(mcu_ext_d_ok),
		.mcu_set_addr(mcu_set_addr),
		.mcu_set_data(mcu_set_data),
		.mcu_rd_data(mcu_rd_hub),

		//L9显示数据接口
		.vs_L9(vs_L9),
		.ds_L9(ds_L9),
		.data_L9(data_L9),
		.h_start_L9(h_start_L9),
		.h_num_L9(h_num_L9),
		.l2048_mode(l2048_mode),

		.state(state),
		.color_restore_type(color_restore_type),
		.testmode(testmode),
		.cascade_light(cascade_light),

		//Artnet显示数据接口
		.input_artnet(input_artnet),
		.ds_a(ds_a),
		.data_a(data_a),
		.h_start_a(h_start_a),
		.h_num_a(h_num_a),

		//背板控制接口
		.device_port(device_port),
		.fpga_dmx_send(dmx_send_flag),
		.mcu_dmx_ten(mcu_dmx_ten),
		
		//SD卡模块接口
		.sd_valid(1'b0),
		.sd_play_flag(1'b0),
		.mcu_sd_miso(1'b0),
		.mcu_sd_en(),
		
		//SD发送数据包接口
		.force_send_play(1'b0),
		.send_flag_dis(1'b0),
		.pre_flag_dis(1'b0),
		.send_data_dis(8'h0),

		//调试接口
		.tout()   
		);

//**************************************************************
//		        显示控制模块
//************************************************************** 
display_top display_top(
		//复位&时钟
		.resetb			(resetb),
		.sclk			(sclk),
		.oclk			(oclk),

		.time_us		(time_us),
		.sync_us		(sync_us),

		//PHY设置总线
		.set_d_ok		(set_d_ok),
		.set_addr		(set_addr),
		.set_data		(set_data),
		.rd_data		(rd_data),

		//MCU设置接口
		.cmd_d_ok		(mcu_ext_d_ok),
		.cmd_addr		(mcu_set_addr),
		.cmd_data		(mcu_set_data),
		.cmd_rd_d		(mcu_rd_hub),

		//MCU辅助通讯
		.mcu_dmx_ten		(mcu_dmx_ten),
		.mcu_dmx_tx		(mcu_dmx_tx),
		.mcu_dmx_rx		(mcu_dmx_rx),

		//控制信号
		.init_mode		(init_mode),
		.device_port		(device_port),
		
		.local_dis_flag		(local_dis_flag),
		.input_artnet		(input_artnet),
		.input_L9		(input_L9),
		.v_start		(vs),
		
		//显示设置包信号
		.state			(state[7:0]),
		.state_2		(state[15:8]),
		.cascade_light		(cascade_light),
		.testmode		(testmode),

		//显示数据读接口
		.frame_buf_sel		(frame_buf_sel), 
		.mem_read_req		(mem_read_req),
        	.mem_read_last		(mem_read_last),
		.mem_h_addr		(mem_h_addr), 
		.mem_l_addr		(mem_l_addr), 
		.mem_read_ack		(mem_read_ack), 
                .mem_data_sync		(mem_data_sync),
		.mem_read_data		(mem_read_data), 
		
		//端口输入输出
		.port_da		(port_da),
		.port_le		(port_le),
		.port_ex		(port_ex),
		
		//调试信号
		.tout			(out_tout)
		);

//**************************************************************
//         		SD卡控制接口
//************************************************************** 


assign force_dis_en = 0;
assign sd_play_en = 0;
assign sd_valid = 0;
assign mcu_play_en = 0;

assign vs_sd = 0;
assign ds_sd = 0;
assign data_sd = 8'h0;
assign h_start_sd = 0;
assign h_num_sd = 11'h0;

//MCU播放测试效果使能
always @(posedge sclk)
	if ((local_dis_flag == 1) && (mcu_play_en == 1))
		mcu_play_flag <= 1;
	else
		mcu_play_flag <= 0;

//SD卡显示使能判断
always @(posedge sclk)
	if (force_dis_en == 1)
		local_dis_flag <= 1;
	else if ((input_L9 == 1) || (input_artnet == 1))
		local_dis_flag <= 0;
	else if ((sd_play_en == 1) && ((sd_valid == 1) || (mcu_play_en == 1)))
		local_dis_flag <= 1;
	else
		local_dis_flag <= 0;

//**************************************************************
//         		显示数据选通
//************************************************************** 
//34ms计数
always @(posedge sclk)
	if (sync_us[10] == 1) begin
		if (count_34ms == 33)
			count_34ms <= 0;
		else
			count_34ms <= count_34ms + 1;
		end

always @( * )
	vs_34ms = count_34ms[5];
	
//帧信号选通
always @(posedge sclk)
	if (local_dis_flag == 1)
		vs <= vs_sd;
	else if (input_L9 == 1)
		vs <= vs_L9;
	else
		vs <= vs_34ms;

//显示数据选通，MCU有优先控制权
always @(posedge sclk)
	if (local_dis_flag == 1)begin
		ds <= ds_sd;
		h_num <= h_num_sd;
		data <= data_sd;
		h_start <= h_start_sd;
		end
	else if (input_artnet == 1) begin
		ds <= ds_a;
		h_num <= h_num_a;
		data <= data_a;
		h_start <= h_start_a;
		end
	else begin //if (input_L9 == 1) begin
		ds <= ds_L9;
		h_num <= h_num_L9;
		data <= data_L9;
		h_start <= h_start_L9;
		end

//**************************************************************
//         		SDRAM控制接口
//************************************************************** 
L9_sdram_top_01 sdram_top(
		//复位和时钟
		.resetb(resetb),
		.sclk(sclk),
		.sync_16us(sync_us[4]),
		
		.init_mode(init_mode),
	
		//写显示数据接口
		.vsin(vs),
		.dsin(ds),
		.din(data),
		.h_start(h_start),
		.h_num(h_num),
		.l2048_mode(l2048_mode),
		.input_artnet(input_artnet),
        
		//显示数据读接口
		.frame_buf_sel		(frame_buf_sel), 
		.mem_read_req		(mem_read_req),
		.mem_read_last		(mem_read_last),
		.mem_h_addr		(mem_h_addr), 
		.mem_l_addr		(mem_l_addr), 
		.mem_read_ack		(mem_read_ack), 
                .mem_data_sync		(mem_data_sync),
		.mem_read_data		(mem_read_data), 
		
		//sdram接口
	        .sa_clk(),
	        .sa_cnt(sa_cnt),
	        .sa_addr(sa_addr),
	        .sa_bank(sa_bank),
	        .sa_data(sa_data),
	        
		//调试输出
	        .tout(sa_tout)
        	);

assign sa_dqm_l = 0;
assign sa_dqm_h = 0;


//************************************************************/
//		调试接口
//************************************************************/                    
//assign  port_le = {vs_34ms, sd_dat3_cs, sd_dat2, sd_dat1, sd_dat0_sdo, a1_tout[1], a1_tout[0], sd_clk};  
//assign  port_da = {sd_f_tout[0], a1_tout[3], a1_tout[2], send_flag_dis, ds_sd, mcu_spi_mosi, mcu_spi_clk, mcu_spi_fpga};  
//assign  port_da = {sd_f_tout[4:0], mcu_spi_mosi, mcu_spi_clk, mcu_spi_fpga};  
//assign  port_da = {sd_f_tout[15:14], sd_f_tout[11], sd_f_tout[7], sd_f_tout[4], sd_f_tout[2:0]};  
//assign  port_le = sd_f_tout[7:0];
//assign  port_da = sd_f_tout[15:8];

//assign  port_le = {sd_clk,sd_cmd_sdi,sd_dat0_sdo,sd_dat1,sd_dat2,sd_dat3_cs,sd_tout[3],f_work};//send_flag_dis,pre_flag_dis};  
//assign  port_le = a1_tout[15:8];
//assign  port_da = a1_tout;
//assign  port_le = {mcu_spi_fpga, mcu_spi_clk, mcu_spi_mosi, mcu_spi_miso, mcu_fpga_ctrl, mcu_sd_en, mcu_sd_rd};  
//assign  port_da = spi_tout;

//assign	JP202_PIN3 = mcu_spi_fpga;//sys_tout[1];//spi2_cs & mcu_spi_fpga;
//assign	JP202_PIN4 = time_us[15];//ttt_count[9];//spi2_clk | mcu_spi_clk;
//assign	JP202_PIN5 = a1_tout[0];//spi2_mosi | mcu_spi_mosi;

//assign	JP202_PIN3 = hub_tout[4];//mcu_spi_fpga;//sys_tout[1];//spi2_cs & mcu_spi_fpga;
//assign	JP202_PIN4 = hub_tout[3];//a1_tout[3];//time_us[14];//mcu_set_d_ok;//ttt_count[9];//spi2_clk | mcu_spi_clk;
//assign	JP202_PIN5 = hub_tout[6];//sd_play_en;//f_work;//a1_tout[0];//mcu_ext_d_ok;//spi2_mosi | mcu_spi_mosi;

//assign	JP202_PIN3 = out_tout[0];//sd_f_tout[0];
//assign	JP202_PIN4 = out_tout[1];//sd_tout[0];//sd_f_tout[1];
//assign	JP202_PIN5 = out_tout[2];//sd_tout[1];//sd_f_tout[2];
//assign	key_in = out_tout[3];//sd_tout[2];//sd_f_tout[3];

assign	JP202_PIN3 = spi2_cs;//sa_tout[0];//vs;//spi2_cs;
assign	JP202_PIN4 = spi2_clk;//input_L9;//ds;//spi2_clk;
assign	JP202_PIN5 = spi2_mosi;//local_dis_flag;//input_artnet;//spi2_mosi;
assign	key_in = mcu_spi_fpga;//black;//mcu_spi_fpga;

//assign	JP202_PIN3 = mcu_spi_fpga;
//assign	JP202_PIN4 = time_us[14];
//assign	JP202_PIN5 = a1_tout[0];

endmodule
